package com.zcoj.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import com.zcoj.core.model.Constants;
import com.zcoj.pojo.Dto.Problem;
import com.zcoj.pojo.Vo.ProblemCaseVO;
import com.zcoj.service.ProblemCaseService;
import com.zcoj.service.ProblemService;
import com.zcoj.service.XmlParserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author chenbin
 * @version 1.0
 * @description: TODO
 * @date 2023/5/13 19:51
 */
@Service
@Slf4j
public class XmlParserServiceImpl implements XmlParserService {

    @Autowired
    private ProblemService problemService;

    @Autowired
    private ProblemCaseService problemCaseService;


    @Override
    public String fpsXmlParseProblem(String xmlString)throws Exception {

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
        Element element = doc.getDocumentElement();

        //创建题目
        Problem problem=new Problem();
        problem.setTilte(element.getElementsByTagName("title").item(0).getTextContent());
        problem.setContentDescription(extractContent(element.getElementsByTagName("description").item(0).getTextContent()));
        problem.setInputDescription(extractContent(element.getElementsByTagName("input").item(0).getTextContent()));
        problem.setOutputDescription(extractContent(element.getElementsByTagName("output").item(0).getTextContent()));
        problem.setInputCase(element.getElementsByTagName("sample_input").item(0).getTextContent());
        problem.setOutputCase(element.getElementsByTagName("sample_output").item(0).getTextContent());
        problem.setTimeLimit(Integer.parseInt(element.getElementsByTagName("time_limit").item(0).getTextContent())*1000);
        problem.setMemoryLimit(Integer.parseInt(element.getElementsByTagName("memory_limit").item(0).getTextContent()));
        problem.setHint(extractContent(element.getElementsByTagName("hint").item(0).getTextContent()));
        problem.setDifficulty(1);
        problem.setProblemStatus(0);

        Integer pid = problemService.create(problem);
        if(pid!=0){
            String solution = element.getElementsByTagName("solution").item(0).getTextContent();
            String solutionPath= Constants.File.TESTCASE_BASE_FOLDER.getPath()+"/problem_"+pid+"/solution.ans";
            File mkdir = FileUtil.touch(solutionPath);
            if(Objects.nonNull(mkdir)){
                FileWriter fileWriter = new FileWriter(solutionPath);
                fileWriter.write(solution);
            }
            List<String> inputs = parseTestCases(element.getElementsByTagName("test_input"));
            List<String> outputs = parseTestCases(element.getElementsByTagName("test_output"));
            if(inputs.size()!=0){
                for(int i = 0; i < inputs.size(); i++) {
                    String input = inputs.get(i);
                    String output = outputs.get(i);
                    Integer newProblemTestcaseFileStatus = problemService.newProblemTestcaseFile(String.valueOf(i + 1), pid);
                    if(newProblemTestcaseFileStatus!=1){
                        return "导入测试案例错误";
                    }
                    ProblemCaseVO problemCaseVO = new ProblemCaseVO();
                    problemCaseVO.setPid(pid);
                    problemCaseVO.setContent(input);
                    problemCaseVO.setFileName(i + 1 +".in");
                    problemService.writeProblemCase(problemCaseVO);
                    problemCaseVO.setContent(output);
                    problemCaseVO.setFileName(i + 1 +".out");
                    problemService.writeProblemCase(problemCaseVO);
                }
                return "添加成功";
            }else {
                return "测试案例数量为0";
            }
        }else {
            return "题目数据导入错误";
        }

    /*    System.out.println("version:"+element.getAttribute("version"));
        System.out.println("url:"+element.getAttribute("url"));
        System.out.println(element.getElementsByTagName("generator").item(0).getAttributes().getNamedItem("name").getNodeValue());
        System.out.println(element.getElementsByTagName("generator").item(0).getAttributes().getNamedItem("url").getNodeValue());
        System.out.println("title"+element.getElementsByTagName("title").item(0).getTextContent());
        System.out.println("time_limit"+Integer.parseInt(element.getElementsByTagName("time_limit").item(0).getTextContent()));
        System.out.println("memory_limit"+Integer.parseInt(element.getElementsByTagName("memory_limit").item(0).getTextContent()));
        System.out.println("description"+element.getElementsByTagName("description").item(0).getTextContent());
        System.out.println("input"+element.getElementsByTagName("input").item(0).getTextContent());
        System.out.println("output"+element.getElementsByTagName("output").item(0).getTextContent());
        System.out.println("sample_input"+element.getElementsByTagName("sample_input").item(0).getTextContent());
        System.out.println("sample_output"+element.getElementsByTagName("sample_output").item(0).getTextContent());
        System.out.println("test_input"+(element.getElementsByTagName("test_input")));
        System.out.println("test_output"+(element.getElementsByTagName("test_output")));
        System.out.println(parseTestCases(element.getElementsByTagName("test_input")));
        System.out.println((parseTestCases(element.getElementsByTagName("test_output"))));
        System.out.println("hint"+element.getElementsByTagName("hint").item(0).getTextContent());
        System.out.println("source"+element.getElementsByTagName("source").item(0).getTextContent());
        System.out.println("solution"+element.getElementsByTagName("solution").item(0).getTextContent());
     */
    }

    public String extractContent(String input) {
        String pattern = "<span[^>]*>(.*?)</span>";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(input);
        if (m.find()) {
            return m.group(1);
        } else {
            return input;
        }
    }
    private List<String> parseTestCases(NodeList nodeList) {
        List<String> testCases = new ArrayList<>();
        for (int i = 0; i < nodeList.getLength(); i++) {
            testCases.add(nodeList.item(i).getTextContent());
        }
        return testCases;
    }

}
